﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace KeywordAuction.Tactics
{
    public class AlphabetaTactics : ITactics
    {
        public int Depth { get; set; }
       // public int CurrentDepth { get; set; }
        public List<string> AdvertiserIdList { get; set; }
       // public int CurrentIndex { get; set; }
        public Advertiser OwnerAdvertiser{ get; set; }

        public AlphabetaTactics()
        {
            Depth = 1;

        }

        public IStrategy GetStrategy(Advertiser advertiser)
        {
            OwnerAdvertiser = advertiser;
           return goNextDepth(advertiser, advertiser.AttendingAuction); // ownerTactics(advertiser);
        }

        private IStrategy ownerTactics(Advertiser advertiser, AuctionHost host = null)
        {
            AdvertiserIdList = advertiser.AttendingAuction.Advertisers.Where(p => p.Id != advertiser.Id).Select(p => p.Id).ToList();
            var simulationHosts = new List<SimulationAuctionHost>();
            //List<string> ownerOrderList = new List<string>();
            simulationHosts.Add(host.Clone() as SimulationAuctionHost);
            //AuctionHost currentHost = host;
            for (int i = 0; i < Depth; i++)
            {
                var baseHosts = simulationHosts.ToList();
                simulationHosts.Clear();
                foreach (var itemHost in baseHosts)
                {
                    foreach (var item in advertiser.Strategies)
                    {
                        var cloneHost =itemHost.Clone() as SimulationAuctionHost;
                        var cloneAdvertiser = cloneHost.Advertisers.Where(p => p.Id == advertiser.Id).FirstOrDefault();
                        item.Action(cloneAdvertiser);
                        cloneAdvertiser.CurrentStrategy = item;
                        simulationHosts.Add(cloneHost);
                      //  ownerOrderList.Add(advertiser.Id);
                        foreach (var opponent in advertiser.AttendingAuction.Advertisers.Where(p => p.Id != advertiser.Id))
                        {
                            var cloneSimuHosts = simulationHosts.ToList();
                            simulationHosts.Clear();
                            foreach (var simuHost in cloneSimuHosts)
                            {
                                foreach (var opponentStrategy in opponent.Strategies)
                                {
                                    var cloneHost2 = cloneHost.Clone() as SimulationAuctionHost;
                                    var cloneAdvertiser2 = cloneHost2.Advertisers.Where(p => p.Id == advertiser.Id).FirstOrDefault();
                                    cloneHost2.ActorAdvertiser = cloneAdvertiser2;
                                    opponentStrategy.Action(cloneAdvertiser2);
                                    simulationHosts.Add(cloneHost2);
                                    //ownerOrderList.Add(opponent.Id);
                                }
                            }
                        }
                    }
                }
            }
          

            //  ownerOrderList.Reverse();
            var simulationList = simulationHosts.Select(p => new SimulationResult { Host = p, Value = 0 }).ToList();// new List<SimulationResult>();
            for (int i = 0; i < host.Advertisers.Count * Depth; i++)
            {
                var parentHost = simulationList.Select(p => p.Host).GroupBy(p => p.ParentAuctionHost);
                var curretnSimulationList = new List<SimulationResult>();
                //double advertiserMiniMaxValue = double.MaxValue;
                foreach (var item in parentHost)
                {
                    double parentHostAdvertiserMiniMaxValue = double.MaxValue;
                    var currentAuctionResult = new List<SimulationResult>();
                    foreach (var caseHost in item)
                    {
                        var parentHostAdvertiserValue = caseHost.Advertisers.First(p => p.Id == caseHost.ParentAuctionHost.ActorAdvertiser.Id).GetValue();
                        double result = caseHost.Advertisers.First(p => p.Id == caseHost.ActorAdvertiser.Id).GetValue();
                        if (result > parentHostAdvertiserMiniMaxValue)
                        {
                            break;
                        }
                        if (result > currentAuctionResult[0].Value)
                        {
                            currentAuctionResult.Clear();
                            currentAuctionResult.Add(new SimulationResult { Value = result, Host = caseHost });
                        }
                        else if (result == currentAuctionResult[0].Value)
                        {
                            currentAuctionResult.Add(new SimulationResult { Value = result, Host = caseHost });
                        }
                    }
                    parentHostAdvertiserMiniMaxValue = currentAuctionResult.First().Value;
                    curretnSimulationList.AddRange(currentAuctionResult);
                }
                simulationList = curretnSimulationList;
            }

            return simulationList.First().Host.Advertisers.First(p => p.Id == advertiser.Id).CurrentStrategy;
        }

        private IStrategy goNextDepth(Advertiser advertiser, AuctionHost host)
        {
            return ownerTactics(advertiser, host);
        }
    }
}
